home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / blend.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  17.6 KB  |  677 lines

  1. /* blend.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * Pixel blending.
  26.  */
  27.  
  28.  
  29. /*
  30. $Id: blend.c,v 1.14 1995/10/30 15:30:33 brianp Exp $
  31.  
  32. $Log: blend.c,v $
  33.  * Revision 1.14  1995/10/30  15:30:33  brianp
  34.  * pass mask array to DD.read_color_pixels
  35.  *
  36.  * Revision 1.13  1995/08/31  21:30:26  brianp
  37.  * renamed blend() as dd_blend()
  38.  * use *DD.read_color_pixels instead of dd_read_color_pixels
  39.  * introduced CC.NewState convention
  40.  *
  41.  * Revision 1.12  1995/06/12  15:34:31  brianp
  42.  * changed color arrays to GLubyte
  43.  *
  44.  * Revision 1.11  1995/05/31  14:57:10  brianp
  45.  * call gl_read_color_span() instead of dd_read_color_span()
  46.  *
  47.  * Revision 1.10  1995/05/22  21:02:41  brianp
  48.  * Release 1.2
  49.  *
  50.  * Revision 1.9  1995/05/12  19:20:19  brianp
  51.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  52.  *
  53.  * Revision 1.8  1995/03/30  21:09:04  brianp
  54.  * fixed bugs in blend scale factors
  55.  *
  56.  * Revision 1.7  1995/03/24  20:03:44  brianp
  57.  * added missing cases to glBlendEquationEXT
  58.  *
  59.  * Revision 1.6  1995/03/24  16:59:17  brianp
  60.  * fixed blending/logicop bug
  61.  *
  62.  * Revision 1.5  1995/03/13  20:55:02  brianp
  63.  * introduced blend function
  64.  * added rest of logic ops
  65.  * optimized common cases
  66.  *
  67.  * Revision 1.4  1995/03/10  16:45:52  brianp
  68.  * updated for new blending extensions
  69.  *
  70.  * Revision 1.3  1995/03/07  18:58:42  brianp
  71.  * added gl_blend_pixels()
  72.  *
  73.  * Revision 1.2  1995/03/04  19:29:44  brianp
  74.  * 1.1 beta revision
  75.  *
  76.  * Revision 1.1  1995/02/24  14:17:11  brianp
  77.  * Initial revision
  78.  *
  79.  */
  80.  
  81.  
  82. #ifdef DEBUG
  83. #  include <assert.h>
  84. #endif
  85. #include "context.h"
  86. #include "dd.h"
  87. #include "list.h"
  88. #include "macros.h"
  89. #include "pb.h"
  90. #include "span.h"
  91.  
  92.  
  93.  
  94. void glBlendFunc( GLenum sfactor, GLenum dfactor )
  95. {
  96.    if (CC.CompileFlag) {
  97.       gl_save_blendfunc( sfactor, dfactor );
  98.    }
  99.    if (CC.ExecuteFlag) {
  100.       if (INSIDE_BEGIN_END) {
  101.      gl_error( GL_INVALID_OPERATION, "glBlendFunction" );
  102.      return;
  103.       }
  104.  
  105.       switch (sfactor) {
  106.      case GL_ZERO:
  107.      case GL_ONE:
  108.      case GL_DST_COLOR:
  109.      case GL_ONE_MINUS_DST_COLOR:
  110.      case GL_SRC_ALPHA:
  111.      case GL_ONE_MINUS_SRC_ALPHA:
  112.      case GL_DST_ALPHA:
  113.      case GL_ONE_MINUS_DST_ALPHA:
  114.      case GL_SRC_ALPHA_SATURATE:
  115.      case GL_CONSTANT_COLOR_EXT:
  116.      case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
  117.      case GL_CONSTANT_ALPHA_EXT:
  118.      case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
  119.         CC.Color.BlendSrc = sfactor;
  120.         break;
  121.      default:
  122.         gl_error( GL_INVALID_ENUM, "glBlendFunction" );
  123.         return;
  124.       }
  125.  
  126.       switch (dfactor) {
  127.      case GL_ZERO:
  128.      case GL_ONE:
  129.      case GL_SRC_COLOR:
  130.      case GL_ONE_MINUS_SRC_COLOR:
  131.      case GL_SRC_ALPHA:
  132.      case GL_ONE_MINUS_SRC_ALPHA:
  133.      case GL_DST_ALPHA:
  134.      case GL_ONE_MINUS_DST_ALPHA:
  135.      case GL_CONSTANT_COLOR_EXT:
  136.      case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
  137.      case GL_CONSTANT_ALPHA_EXT:
  138.      case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
  139.         CC.Color.BlendDst = dfactor;
  140.         break;
  141.      default:
  142.         gl_error( GL_INVALID_ENUM, "glBlendFunction" );
  143.       }
  144.    }
  145.  
  146.    CC.NewState = GL_TRUE;
  147. }
  148.  
  149.  
  150.  
  151. /*
  152.  * This is not a standard OpenGL function.  It is an extension!
  153.  */
  154. void glBlendEquationEXT( GLenum mode )
  155. {
  156.    if (CC.CompileFlag) {
  157.       /* TODO: redo this so the mode is checked at list execute time */
  158.       gl_save_set_enum( &CC.Color.BlendEquation, mode );
  159.    }
  160.    if (CC.ExecuteFlag) {
  161.       switch (mode) {
  162.      case GL_MIN_EXT:
  163.      case GL_MAX_EXT:
  164.      case GL_LOGIC_OP:
  165.      case GL_FUNC_ADD_EXT:
  166.      case GL_FUNC_SUBTRACT_EXT:
  167.      case GL_FUNC_REVERSE_SUBTRACT_EXT:
  168.         CC.Color.BlendEquation = mode;
  169.         break;
  170.     default:
  171.         gl_error( GL_INVALID_ENUM, "glBlendEquationEXT" );
  172.       }
  173.    }
  174.    CC.NewState = GL_TRUE;
  175. }
  176.  
  177.  
  178.  
  179. /*
  180.  * This is not a standard OpenGL function.  It is an extension!
  181.  */
  182. void glBlendColorEXT( GLclampf red, GLclampf green,
  183.               GLclampf blue, GLclampf alpha )
  184. {
  185.    if (CC.CompileFlag) {
  186.       gl_save_set_float( &CC.Color.BlendColor[0], CLAMP( red,   0.0, 1.0 ) );
  187.       gl_save_set_float( &CC.Color.BlendColor[0], CLAMP( green, 0.0, 1.0 ) );
  188.       gl_save_set_float( &CC.Color.BlendColor[0], CLAMP( blue,  0.0, 1.0 ) );
  189.       gl_save_set_float( &CC.Color.BlendColor[0], CLAMP( alpha, 0.0, 1.0 ) );
  190.    }
  191.    if (CC.ExecuteFlag) {
  192.       CC.Color.BlendColor[0] = CLAMP( red,   0.0, 1.0 );
  193.       CC.Color.BlendColor[1] = CLAMP( green, 0.0, 1.0 );
  194.       CC.Color.BlendColor[2] = CLAMP( blue,  0.0, 1.0 );
  195.       CC.Color.BlendColor[3] = CLAMP( alpha, 0.0, 1.0 );
  196.    }
  197. }
  198.  
  199.  
  200.  
  201. /*
  202.  * Do the real work of gl_blend_span() and gl_blend_pixels().
  203.  * Input:  n - number of pixels
  204.  *         mask - the usual write mask
  205.  * In/Out:  red, green, blue, alpha - the incoming and modified pixels
  206.  * Input:  rdest, gdest, bdest, adest - the pixels from the dest color buffer
  207.  */
  208. static void do_blend( GLuint n, const GLubyte mask[],
  209.                       GLubyte red[], GLubyte green[],
  210.                       GLubyte blue[], GLubyte alpha[],
  211.                       const GLubyte rdest[], const GLubyte gdest[],
  212.                       const GLubyte bdest[], const GLubyte adest[] )
  213. {
  214.    GLfloat rscale, gscale, bscale, ascale;
  215.    GLuint i;
  216.  
  217.  
  218.    rscale = 1.0F / CC.RedScale;
  219.    gscale = 1.0F / CC.GreenScale;
  220.    bscale = 1.0F / CC.BlueScale;
  221.    ascale = 1.0F / CC.AlphaScale;
  222.  
  223.    /* Common cases: */
  224.  
  225.    if (CC.Color.BlendEquation==GL_FUNC_ADD_EXT
  226.        && CC.Color.BlendSrc==GL_SRC_ALPHA
  227.        && CC.Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA) {
  228.       /* Alpha blending */
  229.       for (i=0;i<n;i++) {
  230.      if (mask[i]) {
  231.         GLfloat r, g, b, a;
  232.         GLfloat t = (GLfloat) alpha[i] * ascale;
  233.         r = red[i]   * t + rdest[i] * (1.0F-t);
  234.         g = green[i] * t + gdest[i] * (1.0F-t);
  235.         b = blue[i]  * t + bdest[i] * (1.0F-t);
  236.         a = alpha[i] * t + adest[i] * (1.0F-t);
  237.         red[i]   = (GLint) MIN2( r, CC.RedScale );
  238.         green[i] = (GLint) MIN2( g, CC.GreenScale );
  239.         blue[i]  = (GLint) MIN2( b, CC.BlueScale );
  240.         alpha[i] = (GLint) MIN2( a, CC.AlphaScale );
  241.      }
  242.       }
  243.    }
  244.    else if (CC.Color.BlendEquation==GL_LOGIC_OP
  245.         && CC.Color.LogicOp==GL_XOR) {
  246.       /* XOR drawing */
  247.       for (i=0;i<n;i++) {
  248.      if (mask[i]) {
  249.         red[i]   ^= rdest[i];
  250.         green[i] ^= gdest[i];
  251.         blue[i]  ^= bdest[i];
  252.         alpha[i] ^= adest[i];
  253.      }
  254.       }
  255.    }
  256.  
  257.    /* General cases: */
  258.  
  259.    else if (CC.Color.BlendEquation==GL_FUNC_ADD_EXT
  260.          || CC.Color.BlendEquation==GL_FUNC_SUBTRACT_EXT
  261.          || CC.Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
  262.       for (i=0;i<n;i++) {
  263.      if (mask[i]) {
  264.         GLint Rs, Gs, Bs, As;  /* Source colors */
  265.         GLint Rd, Gd, Bd, Ad;  /* Dest colors */
  266.         GLfloat sR, sG, sB, sA;  /* Source scaling */
  267.         GLfloat dR, dG, dB, dA;  /* Dest scaling */
  268.         GLfloat r, g, b, a;
  269.  
  270.         /* Source Color */
  271.         Rs = red[i];
  272.         Gs = green[i];
  273.         Bs = blue[i];
  274.         As = alpha[i];
  275.  
  276.         /* Frame buffer color */
  277.         Rd = rdest[i];
  278.         Gd = gdest[i];
  279.         Bd = bdest[i];
  280.         Ad = adest[i];
  281.  
  282.         /* Source scaling */
  283.         switch (CC.Color.BlendSrc) {
  284.            case GL_ZERO:
  285.           sR = sG = sB = sA = 0.0F;
  286.           break;
  287.            case GL_ONE:
  288.           sR = sG = sB = sA = 1.0F;
  289.           break;
  290.            case GL_DST_COLOR:
  291.           sR = (GLfloat) Rd * rscale;
  292.           sG = (GLfloat) Gd * gscale;
  293.           sB = (GLfloat) Bd * bscale;
  294.           sA = (GLfloat) Ad * ascale;
  295.           break;
  296.            case GL_ONE_MINUS_DST_COLOR:
  297.           sR = 1.0F - (GLfloat) Rd * rscale;
  298.           sG = 1.0F - (GLfloat) Gd * gscale;
  299.           sB = 1.0F - (GLfloat) Bd * bscale;
  300.           sA = 1.0F - (GLfloat) Ad * ascale;
  301.           break;
  302.            case GL_SRC_ALPHA:
  303.           sR = sG = sB = sA = (GLfloat) As * ascale;
  304.           break;
  305.            case GL_ONE_MINUS_SRC_ALPHA:
  306.           sR = sG = sB = sA = (GLfloat) 1.0F - (GLfloat) As * ascale;
  307.           break;
  308.            case GL_DST_ALPHA:
  309.           sR = sG = sB = sA =(GLfloat) Ad * ascale;
  310.           break;
  311.            case GL_ONE_MINUS_DST_ALPHA:
  312.           sR = sG = sB = sA = 1.0F - (GLfloat) Ad * ascale;
  313.           break;
  314.            case GL_SRC_ALPHA_SATURATE:
  315.           if (As < 1.0F - (GLfloat) Ad * ascale) {
  316.              sR = sG = sB = (GLfloat) As * ascale;
  317.           }
  318.           else {
  319.              sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
  320.           }
  321.           sA = 1.0;
  322.           break;
  323.            case GL_CONSTANT_COLOR_EXT:
  324.           sR = CC.Color.BlendColor[0];
  325.           sG = CC.Color.BlendColor[1];
  326.           sB = CC.Color.BlendColor[2];
  327.           sA = CC.Color.BlendColor[3];
  328.           break;
  329.            case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
  330.           sR = 1.0F - CC.Color.BlendColor[0];
  331.           sG = 1.0F - CC.Color.BlendColor[1];
  332.           sB = 1.0F - CC.Color.BlendColor[2];
  333.           sA = 1.0F - CC.Color.BlendColor[3];
  334.           break;
  335.            case GL_CONSTANT_ALPHA_EXT:
  336.           sR = sG = sB = sA = CC.Color.BlendColor[3];
  337.           break;
  338.            case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
  339.           sR = sG = sB = sA = 1.0F - CC.Color.BlendColor[3];
  340.           break;
  341.            default:
  342.           gl_error( GL_INVALID_ENUM, "gl_blend source" );
  343.         }
  344.  
  345.         /* Dest scaling */
  346.         switch (CC.Color.BlendDst) {
  347.            case GL_ZERO:
  348.           dR = dG = dB = dA = 0.0F;
  349.           break;
  350.            case GL_ONE:
  351.           dR = dG = dB = dA = 1.0F;
  352.           break;
  353.            case GL_SRC_COLOR:
  354.           dR = (GLfloat) Rs * rscale;
  355.           dG = (GLfloat) Gs * gscale;
  356.           dB = (GLfloat) Bs * bscale;
  357.           dA = (GLfloat) As * ascale;
  358.           break;
  359.            case GL_ONE_MINUS_SRC_COLOR:
  360.           dR = 1.0F - (GLfloat) Rs * rscale;
  361.           dG = 1.0F - (GLfloat) Gs * gscale;
  362.           dB = 1.0F - (GLfloat) Bs * bscale;
  363.           dA = 1.0F - (GLfloat) As * ascale;
  364.           break;
  365.            case GL_SRC_ALPHA:
  366.           dR = dG = dB = dA = (GLfloat) As * ascale;
  367.           break;
  368.            case GL_ONE_MINUS_SRC_ALPHA:
  369.           dR = dG = dB = dA = (GLfloat) 1.0F - (GLfloat) As * ascale;
  370.           break;
  371.            case GL_DST_ALPHA:
  372.           dR = dG = dB = dA = (GLfloat) Ad * ascale;
  373.           break;
  374.            case GL_ONE_MINUS_DST_ALPHA:
  375.           dR = dG = dB = dA = 1.0F - (GLfloat) Ad * ascale;
  376.           break;
  377.            case GL_CONSTANT_COLOR_EXT:
  378.           dR = CC.Color.BlendColor[0];
  379.           dG = CC.Color.BlendColor[1];
  380.           dB = CC.Color.BlendColor[2];
  381.           dA = CC.Color.BlendColor[3];
  382.           break;
  383.            case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
  384.           dR = 1.0F - CC.Color.BlendColor[0];
  385.           dG = 1.0F - CC.Color.BlendColor[1];
  386.           dB = 1.0F - CC.Color.BlendColor[2];
  387.           dA = 1.0F - CC.Color.BlendColor[3];
  388.           break;
  389.            case GL_CONSTANT_ALPHA_EXT:
  390.           dR = dG = dB = dA = CC.Color.BlendColor[3];
  391.           break;
  392.            case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
  393.           dR = dG = dB = dA = 1.0F - CC.Color.BlendColor[3] * ascale;
  394.           break;
  395.            default:
  396.           gl_error( GL_INVALID_ENUM, "gl_blend dest" );
  397.         }
  398.  
  399. #ifdef DEBUG
  400.         assert( sR>= 0.0 && sR<=1.0 );
  401.         assert( sG>= 0.0 && sG<=1.0 );
  402.         assert( sB>= 0.0 && sB<=1.0 );
  403.         assert( sA>= 0.0 && sA<=1.0 );
  404.         assert( dR>= 0.0 && dR<=1.0 );
  405.         assert( dG>= 0.0 && dG<=1.0 );
  406.         assert( dB>= 0.0 && dB<=1.0 );
  407.         assert( dA>= 0.0 && dA<=1.0 );
  408. #endif
  409.  
  410.         /* compute blended color */
  411.         if (CC.Color.BlendEquation==GL_FUNC_ADD_EXT) {
  412.            r = Rs * sR + Rd * dR;
  413.            g = Gs * sG + Gd * dG;
  414.            b = Bs * sB + Bd * dB;
  415.            a = As * sA + Ad * dA;
  416.         }
  417.         else if (CC.Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
  418.            r = Rs * sR - Rd * dR;
  419.            g = Gs * sG - Gd * dG;
  420.            b = Bs * sB - Bd * dB;
  421.            a = As * sA - Ad * dA;
  422.         }
  423.         else if (CC.Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
  424.            r = Rd * dR - Rs * sR;
  425.            g = Gd * dG - Gs * sG;
  426.            b = Bd * dB - Bs * sB;
  427.            a = Ad * dA - As * sA;
  428.         }
  429.         red[i]   = (GLint) CLAMP( r, 0.0, CC.RedScale );
  430.         green[i] = (GLint) CLAMP( g, 0.0, CC.GreenScale );
  431.         blue[i]  = (GLint) CLAMP( b, 0.0, CC.BlueScale );
  432.         alpha[i] = (GLint) CLAMP( a, 0.0, CC.AlphaScale );
  433.      }
  434.       }
  435.    }
  436.  
  437.    else if (CC.Color.BlendEquation==GL_LOGIC_OP) {
  438.       /* EXTENSION */
  439.       switch (CC.Color.LogicOp) {
  440.      case GL_CLEAR:
  441.         for (i=0;i<n;i++) {
  442.            if (mask[i]) {
  443.           red[i] = green[i] = blue[i] = alpha[i] = 0;
  444.            }
  445.         }
  446.         break;
  447.      case GL_SET:
  448.         for (i=0;i<n;i++) {
  449.            if (mask[i]) {
  450.           red[i]   = (GLint) CC.RedScale;
  451.           green[i] = (GLint) CC.GreenScale;
  452.           blue[i]  = (GLint) CC.BlueScale;
  453.           alpha[i] = (GLint) CC.AlphaScale;
  454.            }
  455.         }
  456.         break;
  457.      case GL_COPY:
  458.         /* do nothing */
  459.         break;
  460.      case GL_COPY_INVERTED:
  461.         for (i=0;i<n;i++) {
  462.            if (mask[i]) {
  463.           red[i]   = !red[i];
  464.           green[i] = !green[i];
  465.           blue[i]  = !blue[i];
  466.           alpha[i] = !alpha[i];
  467.            }
  468.         }
  469.         break;
  470.      case GL_NOOP:
  471.         for (i=0;i<n;i++) {
  472.            if (mask[i]) {
  473.           red[i]   = rdest[i];
  474.           green[i] = gdest[i];
  475.           blue[i]  = bdest[i];
  476.           alpha[i] = adest[i];
  477.            }
  478.         }
  479.         break;
  480.      case GL_INVERT:
  481.         for (i=0;i<n;i++) {
  482.            if (mask[i]) {
  483.           red[i]   = !rdest[i];
  484.           green[i] = !gdest[i];
  485.           blue[i]  = !bdest[i];
  486.           alpha[i] = !adest[i];
  487.            }
  488.         }
  489.         break;
  490.      case GL_AND:
  491.         for (i=0;i<n;i++) {
  492.            if (mask[i]) {
  493.           red[i]   &= rdest[i];
  494.           green[i] &= gdest[i];
  495.           blue[i]  &= bdest[i];
  496.           alpha[i] &= adest[i];
  497.            }
  498.         }
  499.         break;
  500.      case GL_NAND:
  501.         for (i=0;i<n;i++) {
  502.            if (mask[i]) {
  503.           red[i]   = !(red[i]   & rdest[i]);
  504.           green[i] = !(green[i] & gdest[i]);
  505.           blue[i]  = !(blue[i]  & bdest[i]);
  506.           alpha[i] = !(alpha[i] & adest[i]);
  507.            }
  508.         }
  509.         break;
  510.      case GL_OR:
  511.         for (i=0;i<n;i++) {
  512.            if (mask[i]) {
  513.           red[i]   |= rdest[i];
  514.           green[i] |= gdest[i];
  515.           blue[i]  |= bdest[i];
  516.           alpha[i] |= adest[i];
  517.            }
  518.         }
  519.         break;
  520.      case GL_NOR:
  521.         for (i=0;i<n;i++) {
  522.            if (mask[i]) {
  523.           red[i]   = !(red[i]   | rdest[i]);
  524.           green[i] = !(green[i] | gdest[i]);
  525.           blue[i]  = !(blue[i]  | bdest[i]);
  526.           alpha[i] = !(alpha[i] | adest[i]);
  527.            }
  528.         }
  529.         break;
  530.      case GL_XOR:
  531.         for (i=0;i<n;i++) {
  532.            if (mask[i]) {
  533.           red[i]   ^= rdest[i];
  534.           green[i] ^= gdest[i];
  535.           blue[i]  ^= bdest[i];
  536.           alpha[i] ^= adest[i];
  537.            }
  538.         }
  539.         break;
  540.      case GL_EQUIV:
  541.         for (i=0;i<n;i++) {
  542.            if (mask[i]) {
  543.           red[i]   = !(red[i]   ^ rdest[i]);
  544.           green[i] = !(green[i] ^ gdest[i]);
  545.           blue[i]  = !(blue[i]  ^ bdest[i]);
  546.           alpha[i] = !(alpha[i] ^ adest[i]);
  547.            }
  548.         }
  549.         break;
  550.      case GL_AND_REVERSE:
  551.         for (i=0;i<n;i++) {
  552.            if (mask[i]) {
  553.           red[i]   = red[i]   & !rdest[i];
  554.           green[i] = green[i] & !gdest[i];
  555.           blue[i]  = blue[i]  & !bdest[i];
  556.           alpha[i] = alpha[i] & !adest[i];
  557.            }
  558.         }
  559.         break;
  560.      case GL_AND_INVERTED:
  561.         for (i=0;i<n;i++) {
  562.            if (mask[i]) {
  563.           red[i]   = !red[i]   & rdest[i];
  564.           green[i] = !green[i] & gdest[i];
  565.           blue[i]  = !blue[i]  & bdest[i];
  566.           alpha[i] = !alpha[i] & adest[i];
  567.            }
  568.         }
  569.         break;
  570.      case GL_OR_REVERSE:
  571.         for (i=0;i<n;i++) {
  572.            if (mask[i]) {
  573.           red[i]   = red[i]   | !rdest[i];
  574.           green[i] = green[i] | !gdest[i];
  575.           blue[i]  = blue[i]  | !bdest[i];
  576.           alpha[i] = alpha[i] | !adest[i];
  577.            }
  578.         }
  579.         break;
  580.      case GL_OR_INVERTED:
  581.         for (i=0;i<n;i++) {
  582.            if (mask[i]) {
  583.           red[i]   = !red[i]   | rdest[i];
  584.           green[i] = !green[i] | gdest[i];
  585.           blue[i]  = !blue[i]  | bdest[i];
  586.           alpha[i] = !alpha[i] | adest[i];
  587.            }
  588.         }
  589.         break;
  590.      default:
  591.         ;  /* nothing */
  592.       }
  593.    }
  594.    else if (CC.Color.BlendEquation==GL_MIN_EXT) {
  595.       /* EXTENSION */
  596.       for (i=0;i<n;i++) {
  597.      if (mask[i]) {
  598.         red[i]   = MIN2( red[i],   rdest[i] );
  599.         green[i] = MIN2( green[i], gdest[i] );
  600.         blue[i]  = MIN2( blue[i],  bdest[i] );
  601.         alpha[i] = MIN2( alpha[i], adest[i] );
  602.      }
  603.       }
  604.    }
  605.    else if (CC.Color.BlendEquation==GL_MAX_EXT) {
  606.       /* EXTENSION */
  607.       for (i=0;i<n;i++) {
  608.      if (mask[i]) {
  609.         red[i]   = MAX2( red[i],   rdest[i] );
  610.         green[i] = MAX2( green[i], gdest[i] );
  611.         blue[i]  = MAX2( blue[i],  bdest[i] );
  612.         alpha[i] = MAX2( alpha[i], adest[i] );
  613.      }
  614.       }
  615.    }
  616.  
  617. }
  618.  
  619.  
  620.  
  621.  
  622.  
  623. /*
  624.  * Apply the blending operator to a span of pixels.
  625.  * Input:  n - number of pixels in span
  626.  *         x, y - location of leftmost pixel in span in window coords.
  627.  *         mask - boolean mask indicating which pixels to blend.
  628.  * In/Out:  red, green, blue, alpha - pixel values
  629.  */
  630. void gl_blend_span( GLuint n, GLint x, GLint y,
  631.             GLubyte red[], GLubyte green[],
  632.             GLubyte blue[], GLubyte alpha[],
  633.             GLubyte mask[] )
  634. {
  635.    GLubyte rdest[MAX_WIDTH], gdest[MAX_WIDTH];
  636.    GLubyte bdest[MAX_WIDTH], adest[MAX_WIDTH];
  637.  
  638.    /* Check if device driver can do the work */
  639.    if (CC.Color.BlendEquation==GL_LOGIC_OP && !CC.Color.SWLogicOpEnabled) {
  640.       return;
  641.    }
  642.  
  643.    /* Read span of current frame buffer pixels */
  644.    gl_read_color_span( n, x, y, rdest, gdest, bdest, adest );
  645.  
  646.    do_blend( n, mask, red, green, blue, alpha, rdest, gdest, bdest, adest );
  647. }
  648.  
  649.  
  650.  
  651.  
  652.  
  653. /*
  654.  * Apply the blending operator to an array of pixels.
  655.  * Input:  n - number of pixels in span
  656.  *         x, y - array of pixel locations
  657.  *         mask - boolean mask indicating which pixels to blend.
  658.  * In/Out:  red, green, blue, alpha - array of pixel values
  659.  */
  660. void gl_blend_pixels( GLuint n, const GLint x[], const GLint y[],
  661.               GLubyte red[], GLubyte green[],
  662.               GLubyte blue[], GLubyte alpha[],
  663.               GLubyte mask[] )
  664. {
  665.    GLubyte rdest[PB_SIZE], gdest[PB_SIZE], bdest[PB_SIZE], adest[PB_SIZE];
  666.  
  667.    /* Check if device driver can do the work */
  668.    if (CC.Color.BlendEquation==GL_LOGIC_OP && !CC.Color.SWLogicOpEnabled) {
  669.       return;
  670.    }
  671.  
  672.    /* Read pixels from current color buffer */
  673.    (*DD.read_color_pixels)( n, x, y, rdest, gdest, bdest, adest, mask );
  674.  
  675.    do_blend( n, mask, red, green, blue, alpha, rdest, gdest, bdest, adest );
  676. }
  677.